package com.qing.study.serviceImpl;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.qing.study.comm.Result;
import com.qing.study.constant.ConfigConstant;
import com.qing.study.service.SendSmsService;
import com.qing.study.util.RandomNumUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

@Service
public class SendSmsServiceImpl implements SendSmsService {

    @Resource
    private ConfigConstant configConstant;
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    private static final Logger logger = LoggerFactory.getLogger(SendSmsServiceImpl.class);

    /**
     * 使用AK&SK初始化账号Client
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @return
     * @throws Exception
     */
    public static Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config().setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret);
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }

    @Override
    public Result sendSms(String phoneNum) throws Exception {
        //先去redis根据手机号获取验证码，有值代表未过期可以直接使用
        String code = redisTemplate.opsForValue().get(phoneNum);
        if (!StringUtils.isEmpty(code)) {
            return Result.ok("此手机号" + phoneNum + "验证码未过期，验证码为：" + code);
        }
        //redis没查询到代表过期或者未发送，下方将把验证码和手机号存储到redis，并设置5分钟过期
        //随机生成4位数字填充验证码
        String num = RandomNumUtil.generateRandomNumber(4);
        Map templateParamMap = new HashMap();
        templateParamMap.put("code", num);
        Client client = createClient(configConstant.getAccessKeyId(), configConstant.getAccessKeySecret());
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setSignName("阿里云短信测试")
                .setTemplateCode("SMS_154950909")
                .setPhoneNumbers(phoneNum)
                .setTemplateParam(JSONObject.toJSONString(templateParamMap));
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
            if (sendSmsResponse.getBody().getCode().equals("OK") && sendSmsResponse.getBody().getMessage().equals("OK")) {
                //短信发送成功后，将手机号以及验证码发送到redis中，过期时间5分钟
                redisTemplate.opsForValue().set(phoneNum, num, 5, TimeUnit.MINUTES);
                return Result.ok("消息发送成功！");
            } else {
                return Result.error(500, "验证码发送失败！原因:" + sendSmsResponse.getBody().getMessage());
            }
        } catch (TeaException error) {
            Common.assertAsString(error.message);
            logger.error(error.message);
            return Result.error(500, error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            Common.assertAsString(error.message);
            logger.error(error.message);
            return Result.error(500, error.message);
        }
    }

    @Override
    public Result verifyCodeForLogin(String phoneNum, String code) {
        //手机号和验证码为空则直接返回
        if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(code)) {
            return Result.ok("手机号或验证码不可为空！");
        }

        if(redisTemplate.opsForValue().get(phoneNum) == null){
            return Result.ok("该手机号未曾发送过验证码！");
        }
        //根据手机号获取redis中存储的短信验证码判断与验证码是否一致
        if (redisTemplate.opsForValue().get(phoneNum).equals(code)) {
            return Result.ok("验证成功！");
        } else {
            return Result.ok("请输入正确的验证码！");
        }
    }
}
